"""
    author : mr li
    Email : 848193394@qq.com
    Time : 2021-4-13
    socket and process
"""

"""
    建立连接 
    判断客户端请求类型，执行相应函数（LOGIN，CHAT，EXIT）
    处理用户发送的登录需求，判断执行，返回true或者false结果（是否允许登录）
    通知行为 对每一个登录的用户通知所有人他来了，每当用户退出通知所有用户他退出了
    聊天室   用户进行聊天，每个用户消息所有人都能看到
    '请求头:用户名:消息内容’
"""
from socket import *


class Chat_room():
    def __init__(self):
        self.udp_socket = socket(type=SOCK_DGRAM)
        self.udp_socket.bind(('0.0.0.0', 1942))
        self.__dict = {}

    def judge(self):
        '''
            判断，根据客户端请求头执行相应功能
        '''
        data, addr = self.udp_socket.recvfrom(1024)
        evidence = data.decode().split(':', 2)
        # 如果请求类型为LOGIN则跳转到登录验证函数
        if evidence[0] == 'LOGIN':
            self.__begin(evidence[1], addr)
        # 如果请求类型为CHAT或EXIT则跳转到通知函数
        elif evidence[0] == 'CHAT' or evidence[0] == 'EXIT':
            self.__inform(evidence, addr)

    def __begin(self, username, addr):  # 登录函数
        """
            判断客户端传递来的姓名
            如果用户名存在 ip正确 直接返回pass  用户名不存在 则创建存储客户端数据后返回pass
            用户名存在但ip不正确则返回refuse
        :return: pass/refuse
        """
        print('账号验证中')
        if username in self.__dict.keys():  # 判断是否存在
            if self.__dict[username] == addr[0]:
                self.udp_socket.sendto(b'pass', addr)
            else:
                self.udp_socket.sendto(b'refuse', addr)
        else:  # 不存在则创建
            self.__dict[username] = addr[0]
            self.udp_socket.sendto(b'pass', addr)

    def __inform(self, evidence, addr):
        '''
            分析请求头，如果是CHAT则发布客户端进入聊天室通知，接引客户端进入聊天室
                      如果是EXIT请求发布客户端退出聊天室，关闭客户端连接
        '''
        if evidence[0] == 'CHAT':
            for username, ip in self.__dict.items():
                if username != evidence[1]:
                    print(f'用户{evidence[1]}进入聊天室')
            self.__chat(evidence, addr)

        if evidence[0] == 'EXIT':
            for username, ip in self.__dict.items():
                if username != evidence[1]:
                    print(f'用户{evidence[1]}退出聊天室')
            self.__exit()

    def __chat(self, evidence, addr):
        for username, ip in self.__dict.items():
            if username != evidence[1]:
                message = f'用户{evidence[1]}:{evidence[2]}'.encode()
                self.udp_socket.sendto(message, addr)

    def __exit(self):
        pass

    def main(self):
        while True:
            self.judge()


if __name__ == '__main__':
    chat_room = Chat_room()
    chat_room.main()
